/* ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
*
* Quotek - Sterownik Pompy Ciepla, Projekt DIY
* http://www.quotek.pl
*
* Copyright (C) 2012-2013 Piotr Murawski
*
* Niniejszy program jest wolnym oprogramowaniem; mozesz go
* rozprowadzac dalej i/lub modyfikowac na warunkach Powszechnej
* Licencji Publicznej GNU, wydanej przez Fundacje Wolnego
* Oprogramowania - wedlug wersji 3-ciej tej Licencji lub kt�rejs
* z pozniejszych wersji.
*
* Niniejszy program rozpowszechniany jest z nadzieja iz bedzie on
* uzyteczny - jednak BEZ JAKIEJKOLWIEK GWARANCJI, nawet domyslnej
* gwarancji PRZYDATNOSCI HANDLOWEJ albo PRZYDATNOSCI DO OKRESLONYCH
* ZASTOSOWAN. W celu uzyskania blizszych informacji - Powszechna
* Licencja Publiczna GNU.
*
* Z pewnoscia wraz z niniejszym programem otrzymales tez egzemplarz
* Powszechnej Licencji Publicznej GNU (GNU General Public License);
* jesli nie - napisz do Free Software Foundation, Inc., 675 Mass Ave,
* Cambridge, MA 02139, USA.
*
* Powszechna Licencja GNU znajduje sie w zalaczonym pliku:
* Licencja.txt
*
* Powszechna Licencja GNU dostepna jest rowniez na stronie:
* http://www.gnu.org/licenses/licenses.html
*
*
* nieoficjalne polskie tlumaczenie na
* http://www.gnu.org.pl
*
* ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
*
* Quotek - Heat Pump Controller (DIY)
* http://www.quotek.pl
*
* Copyright (C) 2012 Piotr Murawski
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
*/



#include <fcntl.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <getopt.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/times.h>
#include <netinet/in.h>
#include <poll.h>

#include "top.h"
#include "config_struct.h"
#include "protocol.h"
#include "program_struct.h"
#include "program_print.h"
#include "temperatury_definicje.h"
#include "krzywe_struct.h"
#include "zapisz.h"
#include "polecenia.h"


int M_port;
int M_help=0;
int M_address;
int M_czytaj;
int M_verbose=0;
int M_NoXmlComment=0;
#define MAX_FILE_NAME    256
char M_XmlFile[MAX_FILE_NAME];

sTPolecenia polecenieDef[]=POL_ARRAY;

int ZAP_Termometry(sTCfgTermometry* config, FILE *stream,  int noComment);
int ZAP_Czasy(sTCfgCzasy* configczasy, FILE *stream,  int noComment);
int ZAP_Inne(sTConfigDane* config, FILE *stream,  int noComment);
int ZAP_Wyjscia(sTConfigDane* config, FILE *stream,  int noComment);
int ZAP_Termostaty(sTCfgTermostat* configTemp, FILE *stream,  int noComment);
int ZAP_Usredniania(sTConfigDane* config, FILE *stream,  int noComment);
int ZAP_Programator(sTConfigDane* config, FILE *stream,  int noComment);
int ZAP_TZmian(sTConfigDane* config, FILE *stream,  int noComment);
int ZAP_WejAdc(sTCfgWejscieAdc* pWejAdc, FILE *stream, int noComment);
int ZAP_Manometry(sTCfgPomCis* pPomCis, FILE *stream, int noComment);
int ZAPKRZ_ZapiszKrzywe(TKrzywe* pkrzywe, FILE *stream, int noComment);
int STAT_Status(sTkotStatus* stat, FILE *stream, int xml);
int STAT_StatusKrotki(sTkotStatus* stat, FILE *stream, int xml);
int ZAP_Temperatury(sTCfgTemperatury* configTemp, FILE *stream,  int noComment);
int LOGI_ReadLogs(char* arg1, char* file, int xml);
int CZYTPROG_CzytajPlik(char* fname, sTProgram* program);
int CZYTKRZY_CzytajPlik(char* fname, TKrzKrzywa*  pkrzy);
int PROGPRINT_PrintProgramXml(sTProgram* prog, FILE *stream, int noComment);
int setActiveProgram(char* prognr);
int zaGetProgram(char* filename, char* nr);
int getTempZew(void);
int getDs1820(char* cport);
int getTempCzujnikow(void);
int getTemperatury(char * id);
int setGrzaniewlwyl(char* co, char* wl);
int czytajKrzywe(char* filename);
int getKrzywe(void);
int startPwm(char* pcNumer, char* pcCzas, char* pcOkres, char* pcImpuls);
int statusPwm(char* pcNumer);
int usatwFlagi(char* pflagi);
void xmlHeader(FILE* stream);
void xmlErrorNoResponse(FILE* stream);
int statusFlag(void);



int czytajUst(char* inFile);
int ustRtc(char* przesu);
int sendRequest(int polec, char* reqData, int len,
                           char* outData, int* outLen, int tout);
int status(char* filename, U8 krotki);
int ping(void);
int symuoff(void);
int symuon(char* arg1);

int zapiszUst(char* filename);

void LF_HelpMessage(int level, char* polecenie);
char LF_Options(int argc, char *argv[]);


int polec = 0;



/* MAIN
 *
 */
int main(int argc, char *argv[])
{
    int    lv_FirstArg;
    int    ileParam;
    int    ileParamAlt;
    sTPolecenia* ppol = polecenieDef;

    M_port=atoi(PARAM_Get("IP_PORT"));
    M_address=inet_addr(PARAM_Get("IP_ADRES"));
    M_czytaj=0;
    M_verbose=0;
    M_XmlFile[0]=0;
    
    //printf("sizeof sTProgram %d\n",sizeof(sTProgram));
    //printf("sizeof sTProgAkcja %d\n",sizeof(sTProgAkcja));
    //printf("sizeof sTCfgTermometry %d\n",sizeof(sTCfgTermometry));
    
    //-----------------------------------------------------------------------
    // ustalenie opcji i parametrow
    //-----------------------------------------------------------------------
    if(LF_Options(argc,argv)==KO)
    {
        return -1;
    }
    lv_FirstArg = optind;
    //-----------------------------------------------------------------------

    if((M_help)&&((lv_FirstArg+1)==argc)){
        LF_HelpMessage(1,argv[lv_FirstArg]);
        return -1;
    }else if(M_help){
        LF_HelpMessage(0,NULL);
        return -1;
    }else if((lv_FirstArg+1)>argc){
        ERR("Niepoprawny sposob wywolania narzedzia, brak polecenia!");
        LF_HelpMessage(0,NULL);
        return -1;
    }

    polec=POL_NIC;
    ileParamAlt=-1;
    ileParam   = 0;
    while(ppol->id!=POL_LAST){
    	if(strcmp(argv[lv_FirstArg],ppol->cmd)==0){
    		polec=ppol->id;
            ileParam=ppol->argc;
            if(ppol->argcAlt!=0) ileParamAlt=ppol->argcAlt;
            break;
    	}
    	ppol++;
    }

    if(polec == POL_NIC){
            ERR("Nierozpoznane polecenia \"%s\"!",argv[lv_FirstArg]);            
            LF_HelpMessage(0,NULL);
            return -1;
    }

    if((lv_FirstArg+1+ileParam)!=argc){
        if((ileParamAlt<0) || ((lv_FirstArg+1+ileParamAlt)!=argc)){
            ERR("Za malo(duzo) podanych parametrow dla polecenia \"%s\"!",argv[lv_FirstArg]);
            LF_HelpMessage(1,argv[lv_FirstArg]);
            return -1;
        }
    }

    if((M_verbose)&&(M_XmlFile[0]))
        printf("Wyjscie do pliku XML: \"%s\"\n",M_XmlFile);

    switch(polec)
    {
       case POL_USTAW:  zapiszUst(argv[lv_FirstArg+1]); break;
       case POL_CZYTAJ: czytajUst(NULL); break;
       case POL_SETRTC: ustRtc(argv[lv_FirstArg+1]); break;
       case POL_STATUS: status(NULL,0); break;
       case POL_STATUSKROTKI: status(NULL, 1); break;
       case POL_PING:     ping(); break;
       case POL_SYMULON:  symuon(argv[lv_FirstArg+1]); break;
       case POL_SYMULOFF: symuoff(); break;
       case POL_SYMUTERM: symuterm(argv[lv_FirstArg+1],
                                   argv[lv_FirstArg+2],
                                   argv[lv_FirstArg+3],
                                   argv[lv_FirstArg+4]); break;
       case POL_SYMUWEJ:  symuwej(argv[lv_FirstArg+1],
                                  argv[lv_FirstArg+2]); break;
       case POL_GETLOG:    LOGI_ReadLogs(argv[lv_FirstArg+1],
                                         NULL,0); break;
       case POL_PROGRAM:     zaProgram(argv[lv_FirstArg+1]); break;
       case POL_GETPROGRAM:     zaGetProgram(NULL,argv[lv_FirstArg+1]); break;
       case POL_ACTIVEPROGRAM:  setActiveProgram(argv[lv_FirstArg+1]); break;
       case POL_GETACTIVEPROGRAM:getActiveProgram(); break;
       case POL_LISTAPROGRAMOW:getListaProgramow(); break;       
       case POL_GETZEWTEMP:getTempZew(); break;       
       case POL_TERMDETECT: getDs1820(argv[lv_FirstArg+1]); break;
       case POL_ZUZYCIE:
            if((argc-1-lv_FirstArg)==0) zuzycie(NULL);
            else                        zuzycie(argv[lv_FirstArg+1]);
            break;       
       case POL_REGULACJA:
            if((argc-1-lv_FirstArg)==0) regulacja(NULL);
            else                        regulacja(argv[lv_FirstArg+1],argv[lv_FirstArg+2]);
            break;       
       case POL_RESET: 
            sendRequest(PROTO_CMD_RESET,NULL,0,NULL,NULL, 0);
            break;
       case POL_GET24STAT: getStat(); break;
       case POL_SAMEPOMPY:
    	   samePompy(argv[lv_FirstArg+1],argv[lv_FirstArg+2]);
    	   break;
       case POL_GETENERGIA:
    	   getEnergia();
    	   break;
       case POL_GETCZUJNIKI:
    	   getTempCzujnikow();
    	   break;
       case POL_PORT:  port(argv[lv_FirstArg+1],
                            argv[lv_FirstArg+2]);
           break;
       case POL_TERMOSTAT:  termostat(argv[lv_FirstArg+1],
                                      argv[lv_FirstArg+2]);
           break;
       case POL_TEMPDEF:  definicje();
           break;
       case POL_GETTEMPERATURY: getTemperatury(argv[lv_FirstArg+1]);
           break;
       case POL_GRZWLWYL: setGrzaniewlwyl(argv[lv_FirstArg+1],argv[lv_FirstArg+2]);
           break;
       case POL_CZYTKRZYWE: czytajKrzywe(argv[lv_FirstArg+1]);
           break;
       case POL_ZAPKRZYWE:  getKrzywe();
           break;
       case POL_KRZYWAPRZEBIEG:  getPrzebiegKrzywe(argv[lv_FirstArg+1],
    		                                       argv[lv_FirstArg+2],
    		                                       argv[lv_FirstArg+3]);
           break;
       case POL_CLEARPROGRAMS: clearPrograms();
    	   break;
       case POL_PWMSTART: startPwm(argv[lv_FirstArg+1],
	                               argv[lv_FirstArg+2],
	                               argv[lv_FirstArg+3],
	                               argv[lv_FirstArg+4]); break;
       case POL_PWMSTATUS:statusPwm(argv[lv_FirstArg+1]); break;
       case POL_FLDEF:    FLGI_Definicje();  break;
       case POL_FLCZYTAJ: statusFlag();      break;
       case POL_FLUSATW:  usatwFlagi(argv[lv_FirstArg+1]);  break;

    	   break;

    }

    return 0;
}
//ENDMAIN



/*  LF_Options
 *
 */
char LF_Options(int argc, char *argv[])
{
   const char*  const  lv_short_options ="+hpvx:b";
   const struct option lv_long_options[]={
         {"help"    		, 0,    0,'h'},
         {"adres"   		, 1,    0,'a'},
         {"port"    		, 1,    0,'p'},
         {"verbose" 		, 0,    0,'v'},
         {"xml"     		, 1,    0,'x'},
         {"bezkomentarzy" 	, 0,    0,'b'},
         {NULL      		, 0, NULL,0},};  //required end of array
   int   lv_NextOption;
   int   lv_Tmp;
   char* lv_Par;

   //---------------------------------------------
   // parameters from arguments
   //---------------------------------------------

   //IF (no input parameters)
   if (argc<1)
   {
      return(OK);
   }

   //no error messages from getopt_long
   opterr=0;
   optind=1;

   //DO all options
   do
   {
      lv_NextOption=getopt_long(argc,argv,lv_short_options,
                                lv_long_options,NULL);

      switch (lv_NextOption)
      {
         case '?':
            ERR("Unrecognized Option: %s \n",argv[optind-1]);
            break;


         case 'h': //--help
            M_help=1;            
            return(OK);
            break;

         case 'b': //--bezkomentarzy
            M_NoXmlComment=1; 
            break;
            
         case 'p': //--strona
            if(optarg){
                HELP_atois(optarg, &M_port);
            }
            break;

         case 'a': //--outdir
            if(optarg){
                M_address=inet_addr(optarg);
            }
            break;

         case 'v': //--outdir
            M_verbose = 1;
            break;
            
         case 'x': //--xml
            strncpy(M_XmlFile,optarg,MAX_FILE_NAME);            
            break;
            
         case -1: //end in options
            return(OK);
            break;
         default:
            return(OK);
            break;
      }

   }
   while (lv_NextOption!=-1);
   //ENDDO all options

   return(OK);

}
//ENDFUNCTION


void LF_HelpMessage(int level, char* polecenie)
{
   sTPolecenia* ppol = polecenieDef;
   if(level==0){
         printf("-----------------------------------------------------------------\n");
         printf(" Narzedzie konfiguracyjne sterownika Pompy Ciepla 3.41, svn:%d\n",SVN_REVISION);
         printf("                   http://www.quotek.pl   \n");
         printf("         \n"
                " UZYCIE:\n"
                "         kotek [opcje] polecenie [parametry]\n"
                "         \n"
                " POLECENIA:\n");
         while(ppol->id!=POL_LAST){
        	 printf("         " "%-17s" "%s\n", ppol->cmd, ppol->descr);
        	 ppol++;
         }
         printf("         \n"
                " POMOC DLA POLECEN:\n"
                "         kotek -h <polecenie>\n"
                "         \n");
         printf(" OPCJE:\n");
         printf("    --adres <IP>     adres IP sterownika pompy, domyslnie zmienna \"KOT_IP_ADRES\" \n");
         printf("    --port  <port>   port IP sterownika pompy, domyslnie zmienna \"KOT_IP_PORT\" \n");
         printf("    --verbose|-v     troche wiecej bedzie wyrzucac na ekran\n");
         printf("    --xml|-x  <plik> ustawia tryb zapisu do pliku xml (dla niektorych polecen), \"0\"-ekran\n");
         printf("    --bezkomentarzy|-b  usuwa komentarze w zapisywanych plikach XML\n");
         printf("    --help|-h <polecenie> pomoc dla polecenia\n");
         
         printf("\n");
         printf("----\n");
         printf(" Dl. konfiguracji: %d\n",sizeof(sTConfigDane));
         printf("\n");
               
   }else{
        printf("\n");
        while(ppol->id!=POL_LAST){
             if(strcmp(polecenie,ppol->cmd)==0){
                printf(ppol->help);
             }
        	 ppol++;
        }
   }

}
//LF_HelpMessage


void closeXml(FILE* stream){
    if(stream!=stdout) fclose(stream);
}

int openXml(FILE** streamOut, int* xmlOpt)
{
    FILE* stream;
    if(M_XmlFile[0]){
       *xmlOpt=1;
       if(strcmp(M_XmlFile,"0")==0){
           stream=stdout;
       }else{
          stream=fopen(M_XmlFile,"w");         
          if (stream==NULL){
             ERR("Nie moge otworzyc pliku: \"%s\"",M_XmlFile);
             return(KO);
          }    
       }
       *streamOut=stream;
   }else{
       *xmlOpt=0;
       *streamOut=stdout;
   }    
   return OK;
}


int sendRequest(int polec, char* reqData, int len,
                           char* outData, int* outLen, int tout)
{
    int    sock;
    sTProtoMsg* mesg;    
    sTProtoHeader header;
    U8  bufor[1500];
    U8* buf; 
    int timeout;
    mesg=malloc(sizeof(sTProtoMsg)+len);    
    buf=(U8*)mesg;
    if(len) memcpy(mesg->data,reqData,len);
    mesg->header.magic=PROTO_MAGIC;
    mesg->header.sequence=10;
    mesg->header.response=0;
    mesg->header.cmd=polec;
    mesg->header.result=PROTO_RESOK;
    mesg->header.datalen=len;    
        
    sock = SIEC_Init("0.0.0.0", CONFIG_DEFAULT_PORT); 
    if(sock>0){
        SIEC_SendUdp(sock, M_address ,CONFIG_DEFAULT_PORT,mesg,sizeof(sTProtoHeader)+len);
        {
            int ip;
            int port;
            int res;
            char buf[1000];
            if(tout)timeout=tout;
            else    timeout=2000;
            res=SIEC_Odbierz(sock, &ip, &port, bufor, sizeof(bufor), timeout);
            if(res>0){
                memcpy(&header,bufor,sizeof(sTProtoHeader));
                if(M_verbose) 
                        printf("Odebrana odpowiedz z ip=%d.%d.%d.%d:%d\n\r",
                        ip&0xFF, ip>>8&0xFF, ip>>16&0xFF, ip>>24&0xFF,
                        port);
                if((header.magic==PROTO_MAGIC)&&
                   (header.sequence==mesg->header.sequence)&&                  
                   (header.cmd==mesg->header.cmd)&&
                   (header.response==PROTO_RESPNSE))
                {
                  if(header.result==PROTO_RESOK){
                      if(M_verbose) 
                             printf("Polecenie potwierdzone \n\r");
                      //IF dane w odpowiedzi
                      if(header.datalen){
                         if(M_verbose) 
                              printf("Dane w odpowiedzi o dlugosci:%d \n\r",header.datalen);
                          if(outData) memcpy(outData,
                                             &bufor[sizeof(sTProtoHeader)],
                                             header.datalen);
                          if(outLen) *outLen=header.datalen;
                      }
                      close(sock);
                      return OK;
                  }else{
                      ERR("Polecenie odrzucone!\n");
                      close(sock);
                      return KO;
                  }   
                }
            }else{
                ERR("Brak powierdzenia na wyslane polecenia\n\r");
            }
         }
     }    
    close(sock);
    return KO;
}


int ustRtc(char* przesu)
{
    int      przeSec;
    time_t   lvTime;
    struct   tm  ptm;
    struct timeval tv;
    sTSetRtc setRtc;
    int bezwzgl;
    int yyyy, mm, dd, hh, min, ss;
    char wd1,wd2;
    
    bezwzgl = sscanf(przesu,"%4d/%2d/%2d-%2d:%2d:%2d-%c%c", 
                            &yyyy, &mm, &dd, &hh, &min, &ss, &wd1, &wd2);
    if(bezwzgl==8){
       //ok.
    }else if(sscanf(przesu,"%d",&przeSec)==0){
       ERR("Zly prarametr przesuniecai czasu lub czas bezwledny");
       return KO;
    }

    if(bezwzgl!=8){
        gettimeofday(&tv,NULL);
        lvTime = tv.tv_sec;
        gmtime_r(&lvTime,&ptm);
    
        if(M_verbose)printf("Czas systemu:         %d:%d:%d  %d/%d/%d\n\r",
                ptm.tm_hour,
                ptm.tm_min,
                ptm.tm_sec,
                ptm.tm_year-100+2000,
                ptm.tm_mon+1,
                ptm.tm_mday
              );
    
        if(M_verbose)printf("Przeuniecie: %d[sek]\n",przeSec);
    
        lvTime = tv.tv_sec+przeSec;
        gmtime_r(&lvTime,&ptm);
        printf("Nowy Czas sterownika: %d:%d:%d  %d/%d/%d\n\r",
                ptm.tm_hour,
                ptm.tm_min,
                ptm.tm_sec,
                ptm.tm_year-100+2000,
                ptm.tm_mon+1,
                ptm.tm_mday
              );
        setRtc.godz=ptm.tm_hour;
        setRtc.min=ptm.tm_min;
        setRtc.sek=ptm.tm_sec;
        setRtc.day=ptm.tm_mday;
        setRtc.weekday=ptm.tm_wday;
        setRtc.mon=ptm.tm_mon+1;
        setRtc.year=ptm.tm_year-100+2000;        
    }else{
        setRtc.weekday=20;
        if((wd1=='P')&&(wd2=='N'))setRtc.weekday=1;
        if((wd1=='W')&&(wd2=='T'))setRtc.weekday=2;
        if((wd1=='S')&&(wd2=='R'))setRtc.weekday=3;
        if((wd1=='C')&&(wd2=='Z'))setRtc.weekday=4;
        if((wd1=='P')&&(wd2=='I'))setRtc.weekday=5;
        if((wd1=='S')&&(wd2=='O'))setRtc.weekday=6;
        if((wd1=='N')&&(wd2=='D'))setRtc.weekday=0;
        if(setRtc.weekday==20){
           ERR("Zly dzien tygodnia!");
           return KO;            
        }
        setRtc.godz=hh;
        setRtc.min=min;
        setRtc.sek=ss;
        setRtc.day=dd;
        setRtc.mon=mm;
        setRtc.year=yyyy;        
    }    

        
    return sendRequest(PROTO_CMD_SETRTC,(char*)&setRtc,sizeof(sTSetRtc), NULL,NULL, 0);
}


int czytajUst(char* inFile)
{
    sTConfigDane confData;
    FILE* stream; 
    int xml;   
    int res;
    int lendata;
    res=sendRequest(PROTO_CMD_GETCONFIG,NULL,0,(char*)&confData,&lendata, 0);
	if(openXml(&stream,&xml)!=OK){
		return KO;
	}
    if(res==OK)
    {    
        fprintf(stream,"<pompa CfgVer=\"1.0\">");
        ZAP_Inne(&confData,stream, M_NoXmlComment);
        ZAP_Termometry(confData.termometry,stream, M_NoXmlComment);
        ZAP_Czasy(confData.czasy,stream, M_NoXmlComment);
        ZAP_Temperatury(confData.temperatury,stream, M_NoXmlComment);
        ZAP_Wyjscia(&confData,stream, M_NoXmlComment);        
        ZAP_Termostaty(confData.termostat,stream, M_NoXmlComment);
        ZAP_Usredniania(&confData,stream, M_NoXmlComment);
        ZAP_Regulacje(confData.regulacje,CONFIG_REG_MAXREGULACJI,stream, M_NoXmlComment);
        ZAP_Programator(&confData,stream, M_NoXmlComment);
        ZAP_Stale(confData.stale, CONFIG_REG_MAXSTALYCH,stream, M_NoXmlComment);
        ZAP_TZmian(&confData,stream, M_NoXmlComment);
        ZAP_WejAdc(confData.wejAdc, stream, M_NoXmlComment);
        ZAP_Manometry(confData.pomCis, stream, M_NoXmlComment);

        fprintf(stream,"\r\n");
        fprintf(stream,"</pompa>\n");
//        printf("Ustawienia zapisane: %02X:%02X:%02X  20%02X/%02X/%02X\n\r",
//            confData.czasbcd[0],
//            confData.czasbcd[1],
//            confData.czasbcd[2],
//            confData.databcd[0],
//            confData.databcd[1],
//            confData.databcd[2]);
        
    }else{
       xmlErrorNoResponse(stream);
    }    
    closeXml(stream);
    return res;
}


int zapiszUst(char* filename)
{
    sTConfigDane configdane;
    time_t   lvTime;
    struct   tm  ptm;
    struct timeval tv;
    int    i;

    bzero(&configdane,sizeof(configdane));
    
    //domyslnie wartosci portow wyjsciowych
    configdane.wyPompaCo=1;
    configdane.wyPompaKo=2;
    configdane.wySprezarka=3;
    
    //domyslnie inne spreawy
    configdane.ip=M_address;
    configdane.port=CONFIG_DEFAULT_PORT;
    configdane.uzyjmac=1;
    configdane.dsDokladnie=1;
    configdane.ipmask=0x00FFFFFF;
    configdane.stanPresostatLp=1;
    configdane.stanPresostatHp=1;
    configdane.wejscieLicznik=CONFIG_WEWY_NIEUSTAWIONE;
    configdane.wyjscieTaryfa=CONFIG_WEWY_NIEUSTAWIONE;
    for(i=0; i<CONFIG_REG_MAXSTALYCH; i++){
    	configdane.stale[i].temp=-999;
    }
        
    gettimeofday(&tv,NULL);
    lvTime = tv.tv_sec;
    gmtime_r(&lvTime,&ptm);
    configdane.czasbcd[0]=((ptm.tm_hour/10)<<4)|(ptm.tm_hour%10);
    configdane.czasbcd[1]=((ptm.tm_min/10)<<4)|(ptm.tm_min%10);
    configdane.czasbcd[2]=((ptm.tm_sec/10)<<4)|(ptm.tm_sec%10);
    configdane.databcd[0]=(((ptm.tm_year-100)/10)<<4)|((ptm.tm_year-100)%10);
    configdane.databcd[1]=(((ptm.tm_mon+1)/10)<<4)|((ptm.tm_mon+1)%10);
    configdane.databcd[2]=((ptm.tm_mday/10)<<4)|(ptm.tm_mday%10);
    
    CZYT_CzytajPlik(filename,&configdane);
    if(M_verbose){
        ZAP_Inne(&configdane,stdout, M_NoXmlComment);
        ZAP_Termometry(configdane.termometry,stdout, M_NoXmlComment);
        ZAP_Czasy(configdane.czasy,stdout, M_NoXmlComment);
        ZAP_Temperatury(configdane.temperatury,stdout, M_NoXmlComment);
    }
    return sendRequest(PROTO_CMD_SAVECONFIG,(char*)&configdane,sizeof(sTConfigDane), NULL,NULL, 0);
}




int status(char* filename, U8 krotki)
{
    sTkotStatus stat;
    int res;
    int lendata;
    int xml;
    FILE* stream;
    bzero(&stat,sizeof(sTkotStatus));
    res=sendRequest(PROTO_CMD_GETSTATUS,NULL,0,(char*)&stat,&lendata, 0);
    
	if(openXml(&stream,&xml)!=OK){
		return KO;
	}
    if(res==OK){
        if(krotki){
            STAT_StatusKrotki(&stat,stream,xml);
        }else{
            STAT_Status(&stat,stream,xml);
        }    
        
    }else{
        if(xml)xmlErrorNoResponse(stream);
    }
    if(xml) closeXml(stream);
    
    return res;
}


int ping(void)
{
    int res;
    int i;
    i=0;
    res=KO;
    while(res!=OK)
    {
        res=sendRequest(PROTO_CMD_PING,NULL,0,NULL,NULL, 0);
        printf("Wywolanie PING .... ");
        if(res==OK) printf("JEST!"); 
        else        printf("nie ma"); 
        printf("\n");
        if(res!=OK) sleep(1);
        i++;
        if(i==3) break;
    }
    return res;
}


int symuon(char* arg1)
{
    int res;
    U8 param;
    int param1;
    res=sendRequest(PROTO_CMD_SYMULACJA1,NULL,0,NULL,NULL, 0);
    
    sscanf(arg1,"%d",&param1);
    param = param1;
    res=sendRequest(PROTO_CMD_SYMULACJA2,&param,sizeof(param)+1,
                                         NULL,NULL, 0);
    return res;
}


int symuoff(void)
{
    int res;
    res=sendRequest(PROTO_CMD_SYMULACJAOFF,NULL,0,NULL,NULL, 0);
    return res;
}


int symuterm(char* cnr, char* ctemp, char* cok, char* cawaria)
{
    int nr;
    int ok;
    int awaria;
    double odczyt;
    sTSymuTermo symuTerm;
    if(sscanf(cnr,"%u",&nr)==0){
        ERR("Bledna wartosc: \"%s\"",cnr);
        return 0;
    }
    if(sscanf(cok,"%u",&ok)==0){
        ERR("Bledna wartosc: \"%s\"",cok);
        return 0;
    }
    if(sscanf(cawaria,"%u",&awaria)==0){
        ERR("Bledna wartosc: \"%s\"",cawaria);
        return 0;
    }
    if(sscanf(ctemp,"%e",&odczyt)==0){
        ERR("Bledna wartosc: \"%s\"",ctemp);
        return 0;
    }
    odczyt = atof(ctemp);
    symuTerm.nr=nr;
    symuTerm.ok=ok;
    symuTerm.awaria=awaria;
    odczyt*=10;
    symuTerm.odczyt=(int)(odczyt);
    
    return sendRequest(PROTO_CMD_SYMULTERMO,
                      (char*)&symuTerm,sizeof(sTSymuTermo), NULL,NULL, 0);
}



int symuwej(char* cnr, char* state)
{
    int nr;
    int stat;
    sTSymuWej symuWej;
    
    if(sscanf(cnr,"%u",&nr)==0){
        ERR("Bledna wartosc: \"%s\"",cnr);
        return 0;
    }
    if(sscanf(state,"%u",&stat)==0){
        ERR("Bledna wartosc: \"%s\"",state);
        return 0;
    }
    
    symuWej.nr=nr;
    symuWej.stan=stat;    
    return sendRequest(PROTO_CMD_SYMULWEJ,
                      (char*)&symuWej,sizeof(sTSymuWej), NULL,NULL, 0);
}

int zaProgram(char* filename){
    sTProgram* program;
    int i;
    int res;
    
    program = (sTProgram*)malloc(sizeof(sTProgram)*PROG_MAXPROGRAMOWSTALY);
    
    memset(program,0,sizeof(sTProgram)*PROG_MAXPROGRAMOWSTALY);
    if(CZYTPROG_CzytajPlik(filename, program)==OK){
        
        for(i=0;i<PROG_MAXPROGRAMOWSTALY;i++){
            //IF program odczytany
            if(program[i].klucz==PROG_KLUCZ){
               res=sendRequest(PROTO_CMD_SETPROGRAM,
                   (char*)&program[i],sizeof(sTProgram), NULL,NULL, 10000);
               if(res!=OK) {
                   free(program);
                   return KO;
               }    
            }   
        }
        free(program);
        return OK;
    }else{
        free(program);
        return KO;
    }
}


int zaGetProgram(char* filename, char* nr)
{
    sTkotGetProgram prog;
    FILE* stream; 
    int i;
    int xml;
    int progNr;
    sTProgAkcja* akcja;
    sTkotGetProgramReq  req;          
    int res;
    int lendata;
           
    if(strcmp(nr,"S")!=0){    
        if(sscanf(nr,"%u",&progNr)==0){
            ERR("Bledna wartosc: \"%s\"",nr);
            return 0;
        }
    }else{
        progNr=PROG_PROGRAMSTALY+1;
    }
        
    req.programNr = progNr;
    
    res=sendRequest(PROTO_CMD_GETPROGRAM,(U8*)&req,sizeof(sTkotGetProgramReq),
                    (char*)&prog,&lendata, 0);
	if(openXml(&stream,&xml)!=OK){
		return KO;
	}
    if(res==OK) 
    {    
        //--------------------------------
        //zapis XML
        //--------------------------------
        if(xml){
            PROGPRINT_PrintProgramXml(&prog.program,stream, M_NoXmlComment); 
        }else{        
            //--------------------------------
            //na ekran
            //--------------------------------
            printf("Program nr ........... ");        
            if(prog.program.klucz==PROG_KLUCZ){
                printf("%d\n",prog.program.numerProgramu+1);        
            }else{
                printf("nie zaprogramowany\n");
                return res;
            }    
            printf("Opis ................. %s\n",prog.program.opis);        
            printf("Dogrzanie zewnetrzne . ");
            printf("temp.=%3.1f ",prog.program.dogrzZewTemp*0.1);
            printf("wsp=%u min/C \n",prog.program.dogrzZewWsp);

            printf("Dogrzanie wewn. 1 .... ");
            printf("temp.=%3.1f ",prog.program.dogrzWew1Temp*0.1);
            printf("wsp=%u min/C \n",prog.program.dogrzWew1Wsp);
            
            printf("Dogrzanie wewn. 2 .... ");
            printf("temp.=%3.1f ",prog.program.dogrzWew2Temp*0.1);
            printf("wsp=%u min/C \n",prog.program.dogrzWew2Wsp);
            printf("------------------------------------------\n");
            if(prog.program.klucz==PROG_KLUCZ)  PROGPRINT_PrintProgram(&prog.program);
        }
    }else{
        if(xml)xmlErrorNoResponse(stream);
    }
    if(xml) closeXml(stream);
    return res;
}



int setActiveProgram(char* prognr){
    int res;
    int nr;
    sTkotSetActiveProgram setActPrg;
    
    if(sscanf(prognr,"%u",&nr)==0){
        ERR("Bledna wartosc: \"%s\"",prognr);
        return 0;
    }
    
    if((nr<1)||(nr>PROG_MAXPROGRAMOW)){
        ERR("Bledna wartosc: \"%s\"",prognr);
        return 0;
    }
    
        
    setActPrg.programNr = nr - 1;
printf("setActPrg.programNr=%d [%d]\n",setActPrg.programNr,sizeof(setActPrg));
    
    res=sendRequest(PROTO_CMD_SETACTIVEPROGRAM,(char*)&setActPrg,
                    sizeof(setActPrg),NULL,NULL, 0);
    
    return res;
}



int getActiveProgram(void){
    int res;
    int len;
    sTkotGetActiveProgram getActPrg;
    res=sendRequest(PROTO_CMD_GETACTIVEPROGRAM,NULL,
                    0,(char*)&getActPrg,&len, 0);
    if(res==OK){
       printf("Aktywny program nr ... %d\n",getActPrg.programNr+1);
       printf("Opis ................. %s\n",getActPrg.opis);        
       printf("Status ............... ");        
       if(getActPrg.valid) printf("poprawny\n");        
       else                printf("nie zaprogramowany\n");
    }
    
    return res;
}


int getTempZew(void){
    sTkotGetTempZewResp dane;
    int res;
    int len;
    int i;
    struct   tm  ptm;
    struct   timeval tv;
    time_t   firtTime;

    res=sendRequest(PROTO_CMD_GETTEMPZEW,NULL,
                    0,(char*)&dane,&len, 0);
    if(res==OK){
       printf("Temperatura zewnetrzna\n");
       printf("------------------------------------\n");
       if(dane.valid==0){
          printf("Nie Aktywna lub brak danych!\n");
          return OK;
       }       
       firtTime = dane.dateTime;
       printf("Ostatnie 15 min ......... %5.1f\n",(float)dane.aktTemp*0.1);
       printf("Opozniona i usredniona .. %5.1f\n",(float)dane.delayed*0.1);        
       printf("Historia:\n");
       for(i=0; i<dane.ileHist; i++){
          gmtime_r(&firtTime,&ptm);       
          printf("%3d  ",i+1);   
          printf("%02u/%02u %02u:%02u ", 
                 ptm.tm_mon+1, ptm.tm_mday ,ptm.tm_hour, ptm.tm_min);
          printf("%5.1f ",((float)dane.hist[i])*0.1);   
          printf("\n"); 
          firtTime-=15*60;
       }
       
    }
    
    return res;
    
}



int zuzycie(char* zuzStr){
    int res;
    int nr;
    int len;
    int xml;
    U32 czas;
    FILE* stream;
    
    if(zuzStr!=NULL){
        //----------------------
        // zapis
        //----------------------
        if(sscanf(zuzStr,"%u",&czas)==0){
            ERR("Bledna wartosc: \"%s\"",zuzStr);
            return 0;
        }
        czas=czas*60;
        res=sendRequest(PROTO_CMD_SETZUZYCIE,(char*)&czas,
                        4,NULL,NULL, 0);
    }else{
        //----------------------
        // odczyt
        //----------------------
        
        res=sendRequest(PROTO_CMD_GETZUZYCIE,NULL,
                        0,(char*)&czas,&len, 0);
		if(openXml(&stream,&xml)!=OK){
			return KO;
		}

        if(res==OK){                       
           czas=czas/60; 
            if(!xml){
               printf("Zuzycie sprezarki[godz:min] ... %u:%02u\n",czas / 60,czas % 60);
            }else{
               xmlHeader(stream);
		       fprintf(stream,"   <zuzycie_sprezarki wartmin=\"%u\" warttekst=\"%u:%02u\"/>\n",
                               czas, czas / 60,czas % 60);
               fprintf(stream,"</pompa>\n");
            }   
        }else{
            if(xml)xmlErrorNoResponse(stream);
        }
        if(xml)closeXml(stream);
    }
    
    return res;
}


int getListaProgramow(void){
    int res;
    int xml;
    FILE* stream;    
    int i;
    int len;
    sTkotGetActiveProgram getActPrg[PROG_MAXPROGRAMOWSTALY];
    
    res=sendRequest(PROTO_CMD_GETLISTAROGRAMS,NULL,
                    0,(char*)getActPrg,&len, 0);
	if(openXml(&stream,&xml)!=OK){
		return KO;
	}
    if(res==OK){                       
        if(xml){
           xmlHeader(stream);
           fprintf(stream,"  <programy>\n");
           for(i=0; i<PROG_MAXPROGRAMOWSTALY; i++){
               fprintf(stream,"    <program \n");               
               fprintf(stream,"numer=\"%d\" ",((getActPrg[i].programNr)&0xFF)+1);
               if(i==PROG_PROGRAMSTALY)fprintf(stream,"numer=\"S\" ");
               else           fprintf(stream,"numer=\"%d\" ",((getActPrg[i].programNr)&0xFF)+1);
               fprintf(stream,"opis=\"%s\" ",getActPrg[i].opis);        
               fprintf(stream,"statustekst=\"");        
               if(getActPrg[i].valid) fprintf(stream,"poprawny\" ");        
               else                   fprintf(stream,"nie zaprogramowany\" ");
               fprintf(stream,"status=\"");        
               if(getActPrg[i].valid) fprintf(stream,"1\" ");        
               else                   fprintf(stream,"0\" ");
               printf("aktywny=\"%s\" ",((getActPrg[i].programNr)&0x100)?"1":"0");        
               printf("aktywnytekst=\"%s\" ",((getActPrg[i].programNr)&0x100)?"TAK":"nie");
               printf("/>\n");        
           }    
           fprintf(stream,"  </programy>\n");
           fprintf(stream,"</pompa>\n");
        }else{
           for(i=0; i<PROG_MAXPROGRAMOWSTALY; i++){
               if(i==PROG_PROGRAMSTALY) printf("program nr = S\n");
               else    printf("program nr = %d\n",((getActPrg[i].programNr)&0xFF)+1);
               printf("Opis       = %s\n",getActPrg[i].opis);        
               printf("Status     = ");        
               if(getActPrg[i].valid) printf("poprawny\n");        
               else                printf("nie zaprogramowany\n");
               printf("Aktywny    = %s\n",((getActPrg[i].programNr)&0x100)?"TAK":"nie");        
               printf("\n");        
           }    
        }   
	}else{
		if(xml)xmlErrorNoResponse(stream);
	}
	if(xml)closeXml(stream);
}



int getDs1820(char* cport){
    sTkotGetDs1820 resp;
    sTkotGetDs1820Req req;
    int res;
    int lendata;
    int port;

    bzero(&resp,sizeof(sTkotGetDs1820));
    port = -1;
    if(sscanf(cport,"%u",&port)!=1){
        ERR("Bledna wartosc portu: \"%s\"",cport);
        return 0;
    }
    if((port<1)&&(port>3)){
        ERR("Bledna wartosc portu: \"%s\"",cport);
        return 0;
    }
    req.port=port-1;
    res=sendRequest(PROTO_CMD_DETECT_DS1820,(char*)&req,sizeof(sTkotGetDs1820Req),
                   (char*)&resp,&lendata, 0);
    
    if(res==OK){
         if(resp.found){
            printf("DS1820  ID=%02X%02X%02X%02X%02X%02X%02X%02X\n",
                    resp.id[0],
                    resp.id[1],
                    resp.id[2],
                    resp.id[3],
                    resp.id[4],
                    resp.id[5],
                    resp.id[6],
                    resp.id[7]);        
         }else{
            printf("NIE WYKRYTO DS1820 na PORCIE %d\n",port);        
         }   
    }    
    
    return res;    
}


int regulacja(char* creg, char* val){
    int res;
    int nr;
    int len;
    int xml;
    S32 mres;
    S32 regczas;
    S32 tempIdx;
    FILE* stream;
    float  fl;
    sTkotGetRegulacje regulacje;
    sTkotSetRegulacje setReg;

    
    if(creg!=NULL){
        //----------------------
        // zapis
        //----------------------
    	//IF regulacja czasu
    	if(strcmp(creg,"czas")==0){
			if(sscanf(val,"%u",&regczas)==0){
				ERR("Bledna wartosc: \"%s\"",creg);
				return KO;
			}else if((regczas<-50)||(regczas>50)){
				ERR("Wartosc poza zakresem -/+ 50%%: \"%s\"",creg);
				return KO;
			}
			setReg.idx=0;
			setReg.value=regczas;
    	}else{
    		//regulacja temperatury
			if(sscanf(creg,"%u",&tempIdx)==0){
				ERR("Bledna wartosc numeru temperatury: \"%s\"",creg);
				return KO;
			}else if((tempIdx<1)||(tempIdx>CONFIG_REG_MAXREGULACJI)){
				ERR("Bledna wartosc numeru temperatury: \"%s\" (poza zakresem)",creg);
				return KO;
			}
			setReg.idx=tempIdx;
		    len=sscanf(val,"%f",&fl);
		    if(len!=1){
		 	   ERR("Zla wartosc temperatury. (nie jest liczba)");
			   return KO;
		    }
		    fl*=10.0;
            setReg.value=fl;

    	}
        //----------------------
        mres=0;
        len=0;
        res=sendRequest(PROTO_CMD_REGULACJA,
        		        (char*)&setReg,sizeof(sTkotSetRegulacje),
        		        (char*)&mres,&len, 0);
        switch(mres){
        case 0: return res;
        case SETREG_INACTIVE:
            ERR("Regulacja nieaktywna");
            return KO;
        case SETREG_OUTPFRANGE:
            ERR("Poza zakresem");
            return KO;
        case SETREG_SETBYINPUT:
            ERR("Regulacja wejsciem");
            return KO;
        default:
            ERR("Nizeznany blad");
            return KO;
        }

    }else{
        //----------------------
        // odczyt
        //----------------------

        res=sendRequest(PROTO_CMD_GETREGULACJA,NULL,
                        0,(char*)&regulacje,&len, 0);
		if(openXml(&stream,&xml)!=OK){
			return KO;
		}
        if(res==OK){
        	int i;
            if(!xml){
               printf("Regulacja czasu grzania ... %d%%\n",regulacje.regCzasu);
               printf("Regulacje temperaturowe:\n");
               printf(" nr aktyw.  reg.wejsciem   wartosc  opis\n");
               printf("----------------------------------------\n");
               for(i=0; i<CONFIG_REG_MAXREGULACJI; i++){
            	   printf(" %2d  ",i+1);
            	   printf(" %1d ",regulacje.regulacje[i].activ);
            	   printf("         ");
            	   if(regulacje.regulacje[i].wej>0) printf("%1d",regulacje.regulacje[i].wej);
            	   else                             printf("-");
            	   printf("         %5.1f",regulacje.regulacje[i].value*0.1);
            	   printf("    %s\n",regulacje.regulacje[i].opis);
               }
            }else{
               xmlHeader(stream);
               fprintf(stream,"  <regulacje>\n");
               fprintf(stream,"     <czas wartosc=\"%d\"/>\n",regulacje.regCzasu);
               fprintf(stream,"     <temperatury>\n");
               for(i=0; i<CONFIG_REG_MAXREGULACJI; i++){
            	   if(regulacje.regulacje[i].activ){
					   fprintf(stream,"       <regtemp ");
					   fprintf(stream,"nr=\"%d\" ",i+1);
					   //fprintf(stream,"actyw=\"%d\" ",regulacje.regulacje[i].activ);
					   if(regulacje.regulacje[i].wej>0) fprintf(stream,"wej=\"%d\" ",regulacje.regulacje[i].wej);
					   else                             fprintf(stream,"wej=\"\" ");
					   fprintf(stream,"wartosc=\"%.1f\" ",regulacje.regulacje[i].value*0.1);
					   fprintf(stream,"opis=\"%s\" ",regulacje.regulacje[i].opis);
					   fprintf(stream,"/>\n");
            	   }
               }

               fprintf(stream,"     </temperatury>\n");
               fprintf(stream,"  </regulacje>\n");
               fprintf(stream,"</pompa>\n");
            }   
		}else{
			if(xml)xmlErrorNoResponse(stream);
		}
        if(xml) closeXml(stream);
    }
    
    return res;
}

int getStat(void){
    int res;
    int xml;
    int len;
    FILE* stream;
    sTProtoStatistics stat;

    res=sendRequest(PROTO_CMD_GET24STAT,NULL,
                    0,(char*)&stat,&len, 0);
	if(openXml(&stream,&xml)!=OK){
		return KO;
	}
    if(res==OK){
        if(!xml){
		   printf("Statystyka dobowa \n");
		   printf("------------------------------------\n");
		   printf("Czas grzania godz:min (min). %d:%02d (%d)\n",stat.czasPracy/60,
				                                                stat.czasPracy%60,
				                                                stat.czasPracy);
		   printf("Temp. Zewn. min ............ %5.1f\n",(float)stat.minTempZew*0.1);
		   printf("Temp. Zewn. max ............ %5.1f\n",(float)stat.maxTempZew*0.1);
		   printf("Temp. Zewn. sr  ............ %5.1f\n",(float)stat.sredniaTempZew*0.1);

		   printf("Temp. Wew1. min ............ %5.1f\n",(float)stat.minTempWew1*0.1);
		   printf("Temp. Wew1. max ............ %5.1f\n",(float)stat.maxTempWew1*0.1);
		   printf("Temp. Wew1. sr  ............ %5.1f\n",(float)stat.sredniaTempWew1*0.1);

		   printf("Temp. Wew2. min ............ %5.1f\n",(float)stat.minTempWew2*0.1);
		   printf("Temp. Wew2. max ............ %5.1f\n",(float)stat.maxTempWew2*0.1);
		   printf("Temp. Wew2. sr  ............ %5.1f\n",(float)stat.sredniaTempWew2*0.1);

		   printf("Energia niska tar (pulsy) .. %d\n",stat.energiaImNt);
		   printf("Energia wysoka tar(pulsy) .. %d\n",stat.energiaImWt);
		   printf("Energia calosc (pulsy) ..... %d\n",stat.energiaImCala);

        }else{
               xmlHeader(stream);
               fprintf(stream,"   <statystyka>\n");
               fprintf(stream,"     <temperatury>\n");
               fprintf(stream,"       <temperatura id=\"zew\" typ=\"min\" wartosc=\"%5.1f\"/>\n",
            		                               (float)stat.minTempZew*0.1);
               fprintf(stream,"       <temperatura id=\"zew\" typ=\"max\" wartosc=\"%5.1f\"/>\n",
            		                               (float)stat.maxTempZew*0.1);
               fprintf(stream,"       <temperatura id=\"zew\" typ=\"sr\" wartosc=\"%5.1f\"/>\n",
            		                               (float)stat.sredniaTempZew*0.1);
               fprintf(stream,"       <temperatura id=\"wew1\" typ=\"min\" wartosc=\"%5.1f\"/>\n",
            		                               (float)stat.minTempWew1*0.1);
               fprintf(stream,"       <temperatura id=\"wew1\" typ=\"max\" wartosc=\"%5.1f\"/>\n",
            		                               (float)stat.maxTempWew1*0.1);
               fprintf(stream,"       <temperatura id=\"wew1\" typ=\"sr\" wartosc=\"%5.1f\"/>\n",
            		                               (float)stat.sredniaTempWew1*0.1);
               fprintf(stream,"       <temperatura id=\"wew2\" typ=\"min\" wartosc=\"%5.1f\"/>\n",
            		                               (float)stat.minTempWew2*0.1);
               fprintf(stream,"       <temperatura id=\"wew2\" typ=\"max\" wartosc=\"%5.1f\"/>\n",
            		                               (float)stat.maxTempWew2*0.1);
               fprintf(stream,"       <temperatura id=\"wew2\" typ=\"sr\" wartosc=\"%5.1f\"/>\n",
            		                               (float)stat.sredniaTempWew2*0.1);
               fprintf(stream,"     </temperatury>\n");
               fprintf(stream,"     <energia>\n");
               fprintf(stream,"       <licznik taryfa=\"niska\" impulsy=\"%d\" />\n",stat.energiaImNt);
               fprintf(stream,"       <licznik taryfa=\"wysoka\" impulsy=\"%d\" />\n",stat.energiaImWt);
               fprintf(stream,"       <licznik taryfa=\"obie\" impulsy=\"%d\" />\n",stat.energiaImCala);
               fprintf(stream,"     </energia>\n");
               fprintf(stream,"   </statystyka>\n");
               fprintf(stream,"</pompa>\n");
        }
	}else{
		if(xml)xmlErrorNoResponse(stream);
	}
	if(xml) closeXml(stream);
}




int samePompy(char* timeKol, char* timeCo){
    int res;
    int i;
    U32 times[2];
    if(sscanf(timeKol,"%u",&i)==0){
            ERR("Bledna wartosc: \"%s\"",timeKol);
            return KO;
    }
    times[0]=i*60;
    if(sscanf(timeCo,"%u",&i)==0){
            ERR("Bledna wartosc: \"%s\"",timeKol);
            return KO;
    }
    times[1]=i*60;

    res=sendRequest(PROTO_CMD_SAMEPOMPY,(char*)&times,sizeof(times),
                   NULL,NULL, 0);
    return res;
}



int getEnergia(void){
    int res;
    int xml;
    int len;
    FILE* stream;
    sTEnergia en;

    res=sendRequest(PROTO_CMD_GETENERGIA,NULL,
                    0,(char*)&en,&len, 0);
	if(openXml(&stream,&xml)!=OK){
		return KO;
	}
    if(res==OK){
        if(!xml){
		   printf("Liczniki energii \n");
		   printf("------------------------------------\n");
		   printf("Niska taryfa (impulsy)...... %d\n",en.nt);
		   printf("Wysoka taryfa (impulsy)..... %d\n",en.tot-en.nt);
		   printf("Obie taryfy (impulsy)....... %d\n",en.tot);
        }else{
               xmlHeader(stream);
               fprintf(stream,"     <energia>\n");
               fprintf(stream,"       <licznik taryfa=\"niska\" impulsy=\"%d\" />\n",en.nt);
               fprintf(stream,"       <licznik taryfa=\"wysoka\" impulsy=\"%d\" />\n",en.tot-en.nt);
               fprintf(stream,"       <licznik taryfa=\"obie\" impulsy=\"%d\" />\n",en.tot);
               fprintf(stream,"     </energia>\n");
               fprintf(stream,"</pompa>\n");
        }
	}else{
		if(xml)xmlErrorNoResponse(stream);
	}
	if(xml) closeXml(stream);
}


static const sTCfgTermometryFunckja LC_TermoFuncDek[]=CONFIG_TERMO_FUNKCJA_DECODETABLE;

int getTempCzujnikow(void){
    int res;
    int xml;
    int len;
    FILE* stream;
    sTkotGetTemps temps;
    int i;

    res=sendRequest(PROTO_CMD_GETTEMPERATURY,NULL,
                    0,(char*)&temps,&len, 0);
	if(openXml(&stream,&xml)!=OK){
		return KO;
	}
    if(res==OK){
        if(!xml){
		   printf("Temperatury czujnikow: \n");
		   printf("lp AKT OK   T   Tmin24 Tmax24  Tsr24  Fun  Opis\n");
		   printf("------------------------------------------------\n");
		   for(i=0;i<temps.ile; i++){
 		       if((temps.temperatury[i].info&GETTEMP_ACTIV)==0){
     		       temps.temperatury[i].funckja=CFG_TERMO_FUN_BRAK;
     		       temps.temperatury[i].opis[0]=0;
 		       }
		      printf("%-2u ",i+1);
		      if(temps.temperatury[i].info&GETTEMP_ACTIV){
		    	  printf(" A ");
		      }else{
		    	  printf(" - ");
		      }
		      if(temps.temperatury[i].info&GETTEMP_TERMOK){
		    	  printf(" 1 ");
		      }else{
		    	  printf(" - ");
		      }
		      printf(" %5.1f ",temps.temperatury[i].aktualna*0.1);
		      printf(" %5.1f ",temps.temperatury[i].min24*0.1);
		      printf(" %5.1f ",temps.temperatury[i].max24*0.1);
		      printf(" %5.1f ",temps.temperatury[i].sr24*0.1);
		      printf(" %-4s ",LC_TermoFuncDek[temps.temperatury[i].funckja].xmltag);
              printf("%s ",temps.temperatury[i].opis);
     	      printf("\n");
		   }
        }else{
               xmlHeader(stream);
               fprintf(stream,"   <temperaturyczujnikow>\n");
       		   for(i=0;i<temps.ile; i++){
 		       if((temps.temperatury[i].info&GETTEMP_ACTIV)==0){
     		       temps.temperatury[i].funckja=CFG_TERMO_FUN_BRAK;
     		       temps.temperatury[i].opis[0]=0;
 		       }
               fprintf(stream,"     <temperaturaczujnik ");
 		       fprintf(stream,"nr=\"%d\" ",i+1);
 		       fprintf(stream,"aktywny=\"%d\" ",
 		    		   ((temps.temperatury[i].info&GETTEMP_ACTIV)!=0)?1:0);
 		       fprintf(stream,"ok=\"%d\" ",
 		    		   ((temps.temperatury[i].info&GETTEMP_TERMOK)!=0)?1:0);
 		       fprintf(stream,"funkcja=\"%s\" ",LC_TermoFuncDek[temps.temperatury[i].funckja].xmltag);
 		       fprintf(stream,"t=\"%.1f\" ",temps.temperatury[i].aktualna*0.1);
 		       fprintf(stream,"tmin24=\"%.1f\" ",temps.temperatury[i].min24*0.1);
		       fprintf(stream,"tmax24=\"%.1f\" ",temps.temperatury[i].max24*0.1);
		       fprintf(stream,"tsr24=\"%.1f\" ",temps.temperatury[i].sr24*0.1);
 		       fprintf(stream,"opis=\"%s\" ",temps.temperatury[i].opis);
               fprintf(stream,"/>\n");
       		   }
               fprintf(stream,"   </temperaturyczujnikow>\n");
               fprintf(stream,"</pompa>\n");
        }
	}else{
		if(xml)xmlErrorNoResponse(stream);
	}
	if(xml) closeXml(stream);
}


int port(char* nr, char* stan){
    int res;
    int i;
    U32 portMsg[2];
    if(sscanf(nr,"%u",&i)==0){
            ERR("Bledna wartosc: \"%s\"",nr);
            return KO;
    }
    if((i<1)||(i>16)){
            ERR("Bledna wartosc: \"%s\"",nr);
            return KO;
    }
    portMsg[0]=i;
    if(sscanf(stan,"%u",&i)==0){
            ERR("Bledna wartosc: \"%s\"",stan);
            return KO;
    }
    if((i<0)||(i>1)){
            ERR("Bledna wartosc: \"%s\"",nr);
            return KO;
    }
    portMsg[1]=i;

    res=sendRequest(PROTO_CMD_PORT,(char*)&portMsg,sizeof(portMsg),
                   NULL,NULL, 0);
    return res;
}



int termostat(char* nr, char* stan){
    int tnr;
    int tstan;
    int res;
    sTTermostat terMsg;
    if(sscanf(nr,"%d",&tnr)==0){
            ERR("Bledna wartosc: \"%s\"",nr);
            return KO;
    }
    if((tnr<1)||(tnr>CONFIG_TERMO_MAXTERMOSTATOW)){
            ERR("Bledna wartosc: \"%s\"",nr);
            return KO;
    }
    if(sscanf(stan,"%d",&tstan)==0){
            ERR("Bledna wartosc: \"%s\"",stan);
            return KO;
    }
    if((tstan<0)||(tstan>1)){
            ERR("Bledna wartosc: \"%s\"",stan);
            return KO;
    }

    terMsg.grzanie=tstan;
    terMsg.nr=tnr;

    res=sendRequest(PROTO_CMD_TERMOSTAT,(char*)&terMsg,sizeof(sTTermostat),
                   NULL,NULL, 0);
    return res;
}

int definicje(void){
   extern sTTempDef CZYTPR_TempDef[];
   extern sTTempGrDef CZYTPR_TempGrDef[];
   int i=0;
   int gi=-1;

   printf("Definicje temperatur uzywane w plikach programow: \n");
   printf("Identyfikujac termometr, mozna uzywac \"nr\" lub \"tekst\"\n");
   printf(" nr              id   Opis\n");
   printf("------------------------------------------------\n");
   while(CZYTPR_TempDef[i].idtrs!=NULL){
	  if(gi!=CZYTPR_TempDef[i].gidx){
		  gi=CZYTPR_TempDef[i].gidx;
		  printf("Grupa nr=%d id=\"%s\" - %s: \r\n",gi,CZYTPR_TempGrDef[gi].idtrs,CZYTPR_TempGrDef[gi].longName);
	  }
      printf(" %3d   %12s   %s \r\n",CZYTPR_TempDef[i].gidx*16+CZYTPR_TempDef[i].idx,
    		                     CZYTPR_TempDef[i].idtrs,
    		                     CZYTPR_TempDef[i].longName);
      i++;
   }
   printf("------------------------------------------------\n");

   return OK;
}



int getTemperatury(char * id){
    int res;
    int xml;
    int len;
    FILE* stream;
    sTkotGetLogicTemps temps;
    int  grIdx=-1;
    int  i,ilegr;

    extern sTTempGrDef CZYTPR_TempGrDef[];
    extern sTTempDef CZYTPR_TempDef[];

    //----------------------------
    //ustalmy index grupy
    ilegr=0;
    while(CZYTPR_TempGrDef[ilegr].idtrs!=NULL){
    	if(strcmp(CZYTPR_TempGrDef[ilegr].idtrs,id)==0){
    		grIdx=ilegr;
    	}
    	ilegr++;
    }
    if(grIdx<0){
		i=sscanf(id,"%d",&grIdx);
		if((i!=1)||(grIdx<0)||(grIdx>=ilegr)){
		    ERR("Bledna wartosc indeksu grupy, \"%s\", zobacz polecenie \"definicje\"",id);
			return KO;
		}
    }

    //----------------------------
	if(openXml(&stream,&xml)!=OK){
		return KO;
	}

	//----------------------------
	len=0;
    res=sendRequest(PROTO_CMD_GETLOGICTEMPERATURY,(char*)&grIdx,
                    sizeof(int),(char*)&temps,&len, 0);

    //----------------------------
    if((res==OK)&&(len==sizeof(sTkotGetLogicTemps))){
        if(!xml){
		   printf("Temperatury grupy nr=%d id=\"%s\": \n",temps.groupIndex,
				                                      CZYTPR_TempGrDef[temps.groupIndex].idtrs);
		   printf("lp  temperatura     id      opis\n");
		   printf("------------------------------------------------\n");
		   for(i=0;i<temps.tempCount; i++){
		      printf("% 3u ",i+1);
		      printf(" %5.1f ",temps.temps[i].aktualna*0.1);
		      printf(" %10s ", CZYTPR_TempDef[i+temps.tempFirstIdx].idtrs);
		      printf(" %s ",CZYTPR_TempDef[i+temps.tempFirstIdx].longName);
     	      printf("\n");
		   }
        }else{
        	   int dobra;
               xmlHeader(stream);
                 fprintf(stream,"   <grupatemperatur nr=\"%u\" id=\"%s\">\n",temps.groupIndex,
                    		                  CZYTPR_TempGrDef[temps.groupIndex].idtrs);
               fprintf(stream,"     <temperatury>\n");
			   for(i=0;i<temps.tempCount; i++){
				  dobra=temps.temps[i].aktualna!=-999?1:0;
                  fprintf(stream,"     <temperatura nr=\"%u\" id=\"%s\" name=\"%s\" t=\"%5.1f\" ok=\"%u\">",
                		              i+1,
                		              CZYTPR_TempDef[i+temps.tempFirstIdx].idtrs,
                		              CZYTPR_TempDef[i+temps.tempFirstIdx].longName,
                		              temps.temps[i].aktualna*0.1,
                		              dobra);
				  fprintf(stream,"%.1f",temps.temps[i].aktualna*0.1);
                  fprintf(stream,"</temperatura>\n");
			   }
               fprintf(stream,"     </temperatury>\n");
               fprintf(stream,"   </grupatemperatur>\n");
               fprintf(stream,"</pompa>\n");
        }
	}else{
        ERR("Brak danych w odpowiedzi",id);
		if(xml)xmlErrorNoResponse(stream);
	}
	if(xml) closeXml(stream);
}



int setGrzaniewlwyl(char* co, char* wl){
    int res;
    sTkotSetGrzanieWlWyl  grz;
    grz.co=0;
    if      ((strcmp(co,"cwu")==0)||(strcmp(co,"CWU")==0)) grz.co=SETGRZANIE_CWU;
    else if ((strcmp(co,"co")==0)||(strcmp(co,"CO")==0))   grz.co=SETGRZANIE_CO;
    else{
        ERR("Bledna wartosc, \"%s\" ",co);
		return KO;
    }
    if      (strcmp(wl,"1")==0) grz.wl=1;
    else if (strcmp(wl,"0")==0) grz.wl=0;
    else{
        ERR("Bledna wartosc, \"%s\" ",wl);
		return KO;
    }
    res=sendRequest(PROTO_CMD_GRZANIEWLWYL,
      		        (char*)&grz,sizeof(sTkotSetGrzanieWlWyl),NULL,NULL, 0);
    return res;
}



int czytajKrzywe(char* filename){
    int i,cnt;
    int res;
    TKrzywe     krzywe;
    TKrzywe     krzywe2;
    TKrzKrzywa  krzywaDef[KRZY_MAXDEFINICJIKRZYWYCH];
    U8 matrix[KRZY_MAXKRZYWYCH+1][PROG_MAXPROGRAMOW+1];

    memset(&krzywe,0,sizeof(TKrzywe));
    memset(krzywaDef,0,sizeof(krzywaDef));
    memset(matrix,0,sizeof(matrix));

    if(CZYTKRZY_CzytajPlik(filename, krzywaDef) == OK){
    	cnt = 0;
		//FOR all krzywe
		for(i=0; i<KRZY_MAXDEFINICJIKRZYWYCH; i++){
			if(krzywaDef[i].numer){
				//IF krzywa was already defined
				if(matrix[krzywaDef[i].numer][krzywaDef[i].program]){
					ERR("Powtorna definicja krzywej %d (program=%d), \"%s\"",krzywaDef[i].numer,
																			 krzywaDef[i].program,
																			 krzywaDef[i].opis);
					return KO;
				}else{
					matrix[krzywaDef[i].numer][krzywaDef[i].program] = 1;
					cnt++;
				}
			}
		}

      	//kopiuj pierwsza porcje
       	memcpy(&krzywe.krzywa, &krzywaDef[0], sizeof(TKrzKrzywa) * KRZY_MAXKRZYWYCH);
       	//kopiuj druga porcje
       	memcpy(&krzywe2.krzywa, &krzywaDef[KRZY_MAXKRZYWYCH], sizeof(TKrzKrzywa) * KRZY_MAXKRZYWYCH);

		//printf("%d \n",sizeof(TKrzywe));
		//printf("%d \n",sizeof(sTConfigDane));
		//krzywe.pad=0xBEEF; //bez tego nie printuje
		//ZAPKRZ_ZapiszKrzywe(&krzywe, stdout, 1);

        krzywe.porcja=0;
        res=sendRequest(PROTO_CMD_SETKRZYWE,
      		            (char*)&krzywe,sizeof(TKrzywe),NULL,NULL, 0);

        krzywe2.porcja=1;
        res=sendRequest(PROTO_CMD_SETKRZYWE,
      		            (char*)&krzywe2,sizeof(TKrzywe),NULL,NULL, 0);
        return res;
    }else{
        return KO;
    }
}

int getKrzywe(void){
    int res;
    int xml;
    int len;
    int i;
    U32 porcja;
    FILE* stream;
    TKrzywe  krzyweTab[KRZY_PORCJI];

    for(i=0; i<KRZY_PORCJI; i++){
    	porcja = i;
		res=sendRequest(PROTO_CMD_GETKRZYWE,(char*)&porcja,
						sizeof(U32),(char*)&krzyweTab[i],&len, 0);
		if(res!=OK) return KO;
    }

    if(res==OK){
			if(!xml){
				stream = stdout;
			}else{
			   if(openXml(&stream,&xml)!=OK){
				  return KO;
			   }
			}
            xmlHeader(stream);
			ZAPKRZ_ZapiszKrzywe(krzyweTab, stream, M_NoXmlComment);
            fprintf(stream,"</pompa>\n");
			if(stream!=stdout) closeXml(stream);
    }
}



int getPrzebiegKrzywe(char* krzywaId,char* tmin,char* tmax){
    int res;
    int len;
    int i;
    sTkotGetKrzywePtsReq req;
    sTkotGetKrzywePtsRes resp;

	len=sscanf(krzywaId,"%d",&i);
	if((len!=1)||(i<1)||(i>KRZY_MAXKRZYWYCH)){
		ERR("Bledny numer krzywej, \"%s\"",krzywaId);
		return KO;
	}
    req.krzywanr=i;
	len=sscanf(tmin,"%d",&i);
	if((len!=1)||(i<-99)||(i>200)){
		ERR("Bledny wartosci temperatury minimalnej, \"%s\"",tmin);
		return KO;
	}
    req.tmin=i*10;
	len=sscanf(tmax,"%d",&i);
	if((len!=1)||(i<-99)||(i>200)){
		ERR("Bledny wartosci temperatury maxymalnej, \"%s\"",tmax);
		return KO;
	}
    req.tmax=i*10;
    if(req.tmin>req.tmax){
		ERR("Temperatura minimalne nie moze byc wieksz od maksymalnej");
		return KO;
    }

    req.step=1; //0.1st
    if     ((req.tmax-req.tmin)>500) req.step=10;
    else if((req.tmax-req.tmin)>200) req.step=5;
    else if((req.tmax-req.tmin)>100) req.step=2;
    else if((req.tmax-req.tmin)>50) req.step=1;

    res=sendRequest(PROTO_CMD_GETKRZYWAPTS,(char*) &req,
                    sizeof(req),(char*)&resp,&len, 0);
    if(res==OK){
    	if(resp.krzywanr>0){
//    		FILE* stream;
//    		sprintf(M_XmlFile,"krzywa.js");
//  		    if(openXml(&stream,&xml)!=OK){
//			   return KO;
//		    }

    		printf("var chartTitle=\"krzywa #%d: %s (korekcja %0.1f)   \";\n",resp.krzywanr,
    				                                                          resp.opis,
    				                                                          (float)resp.tkor*0.1);
    		printf("var chartTitleNoKor=\"krzywa #%d (bez korekcji)\";\n",resp.krzywanr);
    		printf("var chartData = [ \n");
        	for(i=0; i<resp.count; i++){
    		    printf("{title: %.1f, value: %f, value2: %f }", (float)(req.tmin+req.step*i)*0.1,
    		    		                                (float)resp.temp[i]*0.1,
    		    		                                ((float)resp.temp[i]-resp.tkor)*0.1);
    		    if(i!=(resp.count-1))printf(",\n");
    		    else                 printf("\n");
           	}
    		printf("];\n");
    		printf("//=============================================================\n");
    		printf("//\n");
    		printf("// Dane dla wykresu \"amCharts\"\n");
    		printf("// Przekieruj wyjscie do pliku \"krzywa.js\" zeby zobaczyc\n");
    		printf("// przebiegi otwierajac plik: \"webchart/index.html\"\n");
    		printf("//\n");
    		printf("// Przyklad:\n");
    		printf("//   \"./kotek przebiegkrzywej 1 -40 40 > krzywa.js\"\n");
    		printf("//\n");
    		printf("//=============================================================\n");
    	}else{
    		ERR("Brak danych, krzywa nie zdefiniowana");
    		return KO;
    	}
    }
}



int clearPrograms(void)
{
    int res;
    int xml;
    res=sendRequest(PROTO_CMD_CLEARPROGRAMS,
      		        NULL,0,NULL,NULL, 20000);
    return res;
}



int startPwm(char* pcNumer, char* pcCzas, char* pcOkres, char* pcImpuls)
{
    int len;
    int nr;
    int czas;
    int okres;
    int impuls;
    sTPwm sPwm;

    int res;

	len=sscanf(pcNumer,"%d",&nr);
	if((len!=1)||(nr<1)||(nr>CONFIG_TERMO_MAXPWM)){
		ERR("Bledny numer wyjscia PWM: \"%s\"",pcNumer);
		return KO;
	}
	len=sscanf(pcCzas,"%d",&czas);
	if((len!=1)||(czas<0)||(czas>(60*24))){
		ERR("Bledny czas PWM: \"%s\"",pcCzas);
		return KO;
	}
	len=sscanf(pcOkres,"%d",&okres);
	if((len!=1)||(okres<1)||(okres>(120))){
			ERR("Bledny okres PWM: \"%s\"",pcOkres);
			return KO;
	}
	len=sscanf(pcImpuls,"%d",&impuls);
	if(len!=1){
		int idx = TEMP_tempIndex(pcImpuls);
		if(idx < 0){
		   ERR("Bledny czas trwania impulsu PWM: \"%s\"",pcImpuls);
		   return KO;
		}
		impuls = idx;
		sPwm.usetempId = 1;
	}else{
	    if((impuls<1)||(impuls>okres)){
		   ERR("Bledny czas trwania impulsu PWM: \"%s\"",pcImpuls);
		   return KO;
	    }
   	    sPwm.usetempId = 0;
	}

	sPwm.nr     = nr;
	sPwm.czas   = czas;
	sPwm.okres  = okres;
	sPwm.impuls = impuls;

    res=sendRequest(PROTO_CMD_STARTPWM,(char*)&sPwm,
                    sizeof(sTPwm),NULL,0, 0);

	return res;
}


int statusPwm(char* pcNumer)
{
    int len;
    int nr;
    int res;
    int xml;
    sTPwmStatus pwmStat;
    FILE* stream;

	len=sscanf(pcNumer,"%d",&nr);
	if((len!=1)||(nr<1)||(nr>CONFIG_TERMO_MAXPWM)){
		ERR("Bledny numer wyjscia PWM: \"%s\"",pcNumer);
		return KO;
	}

    res=sendRequest(PROTO_CMD_STATUSPWM,(char*) &nr,
                    sizeof(nr),(char*)&pwmStat,&len, 0);

    if(res==OK){
			//----------------------------
			if(openXml(&stream,&xml)!=OK){
				return KO;
			}

			if(!xml){
		        printf("Status wyjcia PWM (czasy w min)\n");
		        printf("---------------------------------\n");
		        printf("Wyjscie ............... %d \n", pwmStat.nr);
		        printf("Aktywne ............... %d \n", pwmStat.active);
		        printf("Czas do konca pracy ... %d \n", pwmStat.czas);
		        printf("Okres PWM ............. %d \n", pwmStat.okres);
		        if(pwmStat.impulsTemp){
		        printf("Impuls tempid ......... %s \n", TEMP_getTempIdxStr(pwmStat.impuls));
		        }else{
		        printf("Szer. Impulsu ......... %d \n", pwmStat.impuls);
			    }
		        printf("Poziom na wyjsciu ..... %d \n", pwmStat.stanWyj);
		        printf("\n");
			}else{
				char* imptem = "";
		        if(pwmStat.impulsTemp){
	                imptem = (char*)TEMP_getTempIdxStr(pwmStat.impuls);
		        }
				fprintf(stream,"<pompa>\n");
				fprintf(stream,"    <statuspwm>\n");
		        fprintf(stream,"        <wyjsciepwm  "
		        		              "nr=\"%d\" "
		        		              "aktywne=\"%d\" "
		        		              "czas=\"%d\" "
		        		              "okres=\"%d\" ",
		        		              pwmStat.nr, pwmStat.active, pwmStat.czas,pwmStat.okres);
		        if(pwmStat.impulsTemp){
                     fprintf(stream,"impulstempid=\"%s\" ",imptem);
		        }else{
                     fprintf(stream,"impuls=\"%d\" ",pwmStat.impuls);
		        }
                fprintf(stream,"stanwyjscia=\"%d\" />\n",pwmStat.stanWyj);
				fprintf(stream,"    </statuspwm>\n");
				fprintf(stream,"</pompa>\n");
				closeXml(stream);
			}
    }


	return 0;
}



int statusFlag(void)
{
    int res;
    int xml;
    int len;
    FILE* stream;
    U8 flagiMap[12];

    res=sendRequest(PROTO_CMD_STATUSFLAG,NULL,0,
    		        (char*)&flagiMap,&len, 0);

    if(res==OK){
			//----------------------------
			if(openXml(&stream,&xml)!=OK){
				return KO;
			}

			if(!xml){
                FLGI_Status(flagiMap);
			}else{
				closeXml(stream);
			}
    }

	return 0;
}


int usatwFlagi(char* pflagi)
{
    int res;
	U8  flagi[4];

    if(FLGI_ParseFlags(pflagi, flagi, 4))
	{
		ERR("Bledna lista flag \"%s\"",pflagi);
		return KO;
	}
    res=sendRequest(PROTO_CMD_SETFLAGS,flagi,4,
    		        NULL,NULL, 0);
}



//==============================================================
//  Template
//==============================================================
//int getListaProgramow(void){
//    int res;
//    int xml;
//    FILE* stream;
//
//    if(res==OK){
//        if(openXml(&stream,&xml)!=OK){
//            return KO;
//        }
//        if(!xml){
//        }else{
//        }
//        closeXml(stream);
//    }
//}

void xmlHeaderError(FILE* stream, U8 error){
	fprintf(stream,"<pompa ver=\"1.0\" error=\"%d\">\n", error);
}


void xmlHeader(FILE* stream)
{
    xmlHeaderError(stream, 0);
}


void xmlErrorNoResponse(FILE* stream)
{
    xmlHeaderError(stream, 1);
    fprintf(stream,"</pompa>\n");
}




//- EOF ---------------------------------------------------------------------
